#ifdef WIN32
#include <windows.h>
#endif

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <GL/glut.h>
#include "trace.h"
#include "global.h"
#include "sphere.h"
#include "image_util.h"
#include "scene.h"



int win_width = WIN_WIDTH;
int win_height = WIN_HEIGHT;

GLfloat frame[WIN_HEIGHT][WIN_WIDTH][3];   

float image_width = IMAGE_WIDTH;
float image_height = (float(WIN_HEIGHT) / float(WIN_WIDTH)) * IMAGE_WIDTH;

RGB_float background_clr; 
RGB_float null_clr = {0.0, 0.0, 0.0};  

Point eye_pos = {0.0, 0.0, 0.0};  
float image_plane = -2;          

Spheres *scene = new Sphere[64];

Point light1;
float light1_ambient[3];
float light1_diffuse[3];
float light1_specular[3];

float global_ambient[3];

float decay_a;
float decay_b;
float decay_c;

int step_max = 1;

int shadow_on = 0;

void keyboard(unsigned char key, int x, int y)
{
  switch (key) {
    case 'q':
	    free(scene);
	    exit(0);
	    break;
    case 'w':
	    eye_pos.y-=1;
	    break;
    case 's':
	eye_pos.y+=1;
	break;
    case 'a':
	    eye_pos.x+=1;
	    break;
    case 'd':
	    eye_pos.x-=1;
	    break;
    default:
	    break;
  }
}

void myinit(void) {
  glClearColor(0.0, 0.0, 0.0, 0.0);

  glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
}

void display(void) {
  GLboolean param;

  static int first=100;
  int iStart=GetTickCount();
  if (first)
  {
	  ray_trace();
	  printf("Ray_trace_time=%d\n",GetTickCount()-iStart);
	  iStart=GetTickCount();

	  histogram_normalization();
	  first--;
  }
  


  glLoadIdentity();

  glClear(GL_COLOR_BUFFER_BIT); // clear the background

  glRasterPos2i(0, 0);
  glGetBooleanv(GL_CURRENT_RASTER_POSITION_VALID, &param);
  if (!frame){
    printf("frame is null. \n");
  } else {
    glDrawPixels(win_width, win_height, GL_RGB, GL_FLOAT, frame);
  }
  
  glFlush();
}
int mouse_x=0;
int mouse_y=0;
void MouseClick(int button,int action,int xMouse,int yMouse)
{
	if(button==GLUT_LEFT_BUTTON&&action==GLUT_DOWN)
	{
		mouse_x=xMouse;
		mouse_y=yMouse;
	}
}
void MouseMotion(int xMouse,int yMouse) 
{
	//eye_pos.x=4*(xMouse-256)/256.0;
	//eye_pos.y=4*(yMouse-256)/256.0;
	//mouse_x=xMouse;
	//mouse_y=yMouse;
	eye_pos.x+=4*(mouse_x-xMouse)/256.0;
	eye_pos.y+=4*(yMouse-mouse_y)/256.0;
	if (eye_pos.x<-5)
	{
		eye_pos.x+=10;
	}
	else if (eye_pos.x>5)
	{
		eye_pos.x-=10;
	}
	if (eye_pos.y<-5)
	{
		eye_pos.y+=10;
	}
	else if (eye_pos.y>5)
	{
		eye_pos.y-=10;
	}
	mouse_x=xMouse;
	mouse_y=yMouse;
}

void myReshape(int w, int h) {
  w = win_width;
  h = win_height;

  glViewport(0, 0, w, h);
  glMatrixMode(GL_PROJECTION);
  glLoadIdentity();
  gluOrtho2D(0, w, 0, h);
  glMatrixMode(GL_MODELVIEW);
}

int main(int argc, char** argv) {
  glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH);
  glutInitWindowPosition (0, 0);
  glutInitWindowSize(win_width, win_height);
  glutCreateWindow(argv[0]);
  myinit();
  glutReshapeFunc(myReshape);
  glutKeyboardFunc(keyboard);

  
  if (argc < 4) {
    printf("Missing arguments ... use:\n");
    printf("./raycast [-user | -def] [-shadow | -noshadow] step_max\n");
    return -1;
  }
  
  if (strcmp(argv[1], "-user") != 0) { 
	  set_up_default_scene();
  } else { 
	  set_up_user_scene();
  }

  if (strcmp(argv[2], "-shadow") == 0) {  // shadow on
    shadow_on = 1;
  }

  step_max = atoi(argv[3]);

  glutDisplayFunc(display);
  glutIdleFunc(display);

  glutMotionFunc(MouseMotion);
  glutMouseFunc(MouseClick);


  printf("Press 'q' to quit\n");
  glutMainLoop();

  return 0; 
}
